package Ranking;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Collections;

import Dao.LUDAO;
import DataClasses.Condo;
import DataClasses.Restaurant;
import DataClasses.School;
import DataClasses.Shop;
import DataClasses.Gas;
import DataClasses.Transportation;

public class Ranking {
	/**
	 * Data
	 */
	public List<House1> house = new ArrayList<House1>();
	public List<Restaurant1> rests = new ArrayList<Restaurant1>();
	public List<School1> school = new ArrayList<School1>();
	public List<Shop1> shop = new ArrayList<Shop1>();
	public List<Gas1> gas = new ArrayList<Gas1>();
	public List<Subway1> sub = new ArrayList<Subway1>();
	
	public double weights[] = {1,1,1,1,1,1};
	
	public int neighbour = 1;
	
	/**
	 * Distance Calculation
	 */
	public double distance(double x1, double y1, double x2, double y2){
		double h,v;
		h = x1 - x2;
		v = y1 - y2;
		return h*h+v*v;
	}
	
	
	/**
	 * Data transformation
	 * Condo: string-- Name, double-- price
	 */
	public void transform(LUDAO oldData){
		
		Hashtable<Integer, Object> h;
		
		// Transform House
		h = oldData.getCondo();
		
		for (Object hou: h.values()){
			House1 hou1 = new House1();
			hou1.latitude = ((Condo)hou).getLatitude();
			hou1.longitude = ((Condo)hou).getLongitude();
			hou1.name = ((Condo)hou).getName();
			hou1.price = ((Condo)hou).getPrice();
			hou1.bedroom = ((Condo)hou).getBedroomNunber();
			hou1.livingroom = ((Condo)hou).getLivingroomNumber();
			hou1.parking = ((Condo)hou).getParkingSpot();
			house.add(hou1);
		}
		
		// Transform Restaurant
		h = oldData.getRestaurant();
		
		for (Object re: h.values()){
			Restaurant1 re1 = new Restaurant1();
			re1.latitude = ((Restaurant)re).getLatitude();
			re1.longitude = ((Restaurant)re).getLongitude();
			re1.rate = 1;
			rests.add(re1);
		}
		
		// Transform School
		h = oldData.getSchool();
		
		for (Object sc: h.values()){
			School1 sc1 = new School1();
			sc1.latitude = ((School)sc).getLatitude();
			sc1.longitude = ((School)sc).getLongitude();
			sc1.rate = 1;
			school.add(sc1);
		}
		
		// Transform shop
		h = oldData.getShop();
		
		for (Object sh: h.values()){
			Shop1 sh1 = new Shop1();
			sh1.latitude = ((Shop)sh).getLatitude();
			sh1.longitude = ((Shop)sh).getLongitude();
			sh1.rate = 1;
			shop.add(sh1);
		}
		
		// Transform gas
		h = oldData.getGas();
		
		for (Object g: h.values()){
			Gas1 g1 = new Gas1();
			g1.latitude = ((Gas)g).getLatitude();
			g1.longitude = ((Gas)g).getLongitude();
			g1.rate = 1;
			gas.add(g1);
		}
		
		
		// Transform subway
		h = oldData.getTransportations();
		
		for (Object su: h.values()){
			Subway1 su1 = new Subway1();
			su1.latitude = ((Transportation)su).getLatitude();
			su1.longitude = ((Transportation)su).getLongitude();
			su1.rate = 1;
			sub.add(su1);
		}
	}
	
	/*void transformRest(){
	}
	
	void transformsSchool(){
	}
	
	void transformGas(){
	}
	
	void transformSub(){
	}*/
	
	/**
	 * Sorting
	 */
	
	/**
	 * rating House
	 */
	/*public void rateRest(){
		int nH = house.size();
		int nR  = rests.size(); 
		
		
		for (int i = 0; i < nH; ++i){
			double x1 = house.get(i).latitude;
			double y1 = house.get(i).longitude;
			for (int j = 0; j < nR; ++j){
				double x2 = rests.get(j).latitude;
				double y2 = rests.get(j).longitude;
				Restaurant1 res = rests.get(j);
				res.dis = distance(x1,y1,x2,y2);
			}
		}
		Collections.sort(rests,new RCom());
		
	}
	
	void rateHouse(){
		
	}
	
	void rateSchool(){
		
	}
	
	void rateShop(){
		
	}
	
	void rateGas(){
		
	}
	
	void rateSub(){
		
	}*/
	
	/**
	 * Rating facilities
	 */
	void scoreRest(){
		int nH = house.size();
		int nR = rests.size();
		
		for (int i = 0; i < nR; ++i){
			double x1 = rests.get(i).latitude;
			double y1 = rests.get(i).longitude;
			for (int j = 0; j < nH; ++j){
				double x2 = house.get(j).latitude;
				double y2 = house.get(j).longitude;
				House1 hou = house.get(j);
				hou.dis = distance(x1,y1,x2,y2);
				house.set(j,hou);
			}
			Collections.sort(house, new HCom());
			
			for (int k = 0; k < neighbour; ++k){
				House1 hou = house.get(k);
				hou.resteraunt += rests.get(i).rate;
				house.set(k, hou);
			}
		}		
	}
	
	void scoreSchool(){
		int nH = house.size();
		int nS = school.size();
		
		for (int i = 0; i < nS; ++i){
			double x1 = school.get(i).latitude;
			double y1 = school.get(i).longitude;
			for (int j = 0; j < nH; ++j){
				double x2 = house.get(j).latitude;
				double y2 = house.get(j).longitude;
				House1 hou = house.get(j);
				hou.dis = distance(x1,y1,x2,y2);
				house.set(j,hou);
			}
			Collections.sort(house, new HCom());
			
			for (int k = 0; k < neighbour; ++k){
				House1 hou = house.get(k);
				hou.school += school.get(i).rate;
				house.set(k, hou);
			}
		}		
	}
	
	void scoreShop(){
		int nH = house.size();
		int nS = shop.size();
		
		for (int i = 0; i < nS; ++i){
			double x1 = shop.get(i).latitude;
			double y1 = shop.get(i).longitude;
			for (int j = 0; j < nH; ++j){
				double x2 = house.get(j).latitude;
				double y2 = house.get(j).longitude;
				House1 hou = house.get(j);
				hou.dis = distance(x1,y1,x2,y2);
				house.set(j,hou);
			}
			Collections.sort(house, new HCom());
			
			for (int k = 0; k < neighbour; ++k){
				House1 hou = house.get(k);
				hou.shop += shop.get(i).rate;
				house.set(k, hou);
			}
		}		
	}
	
	void scoreGas(){
		int nH = house.size();
		int nG = gas.size();
		
		for (int i = 0; i < nG; ++i){
			double x1 = gas.get(i).latitude;
			double y1 = gas.get(i).longitude;
			for (int j = 0; j < nH; ++j){
				double x2 = house.get(j).latitude;
				double y2 = house.get(j).longitude;
				House1 hou = house.get(j);
				hou.dis = distance(x1,y1,x2,y2);
				house.set(j,hou);
			}
			Collections.sort(house, new HCom());
			
			for (int k = 0; k < neighbour; ++k){
				House1 hou = house.get(k);
				hou.gas += rests.get(i).rate;
				house.set(k, hou);
			}
		}		
	}
	
	void scoreSubway(){
		int nH = house.size();
		int nS = sub.size();
		
		for (int i = 0; i < nS; ++i){
			double x1 = sub.get(i).latitude;
			double y1 = sub.get(i).longitude;
			for (int j = 0; j < nH; ++j){
				double x2 = house.get(j).latitude;
				double y2 = house.get(j).longitude;
				House1 hou = house.get(j);
				hou.dis = distance(x1,y1,x2,y2);
				house.set(j,hou);
			}
			Collections.sort(house, new HCom());
			
			for (int k = 0; k < neighbour; ++k){
				House1 hou = house.get(k);
				hou.subway += sub.get(i).rate;
				house.set(k, hou);
			}
		}		
	}
	/**
	 * Set Weights
	 */
	void setWeight(double x[]){
		weights = x;
	}
	
	/**
	 * Calculate Final Score
	 */
	void scoreFinal(){
		int nH = house.size();
		for (int i = 0; i < nH; ++i){
			double score = 0;
			score += house.get(i).resteraunt*weights[1];
			score += house.get(i).school*weights[2];
			score += house.get(i).shop*weights[3];
			score += house.get(i).gas*weights[4];
			score += house.get(i).subway*weights[5];
			House1 hou = house.get(i);
			hou.score = score;
			house.set(i, hou);
		}
	}
	
	public void scoreAll(){
		scoreRest();
		scoreSchool();
		scoreShop();
		scoreGas();
		scoreSubway();
		scoreFinal();
		
/*		for (int i = 0; i<house.size(); ++i){
			
		}*/
	}
	/**
	 * 
	 * Get scores
	 */
	public List<House1> getHouse(){
		return house;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Ranking r = new Ranking();
			LUDAO l = new LUDAO();
			r.transform(l);
			r.scoreAll();			
	}

}
